package com.ias.common.utils.json;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Map;

/**
 * JSON工具类 - 基于Jackson实现
 * 提供常用的JSON序列化和反序列化操作
 *
 * @author IAS
 * @since 1.0.0
 */
@Slf4j
public class JsonUtil {

    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

    static {
        // 配置ObjectMapper
        OBJECT_MAPPER.registerModule(new JavaTimeModule());
        // 忽略未知属性
        OBJECT_MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        // 忽略空属性
        OBJECT_MAPPER.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
        // 日期格式化为时间戳
        OBJECT_MAPPER.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
        // 空字符串转换为null
        OBJECT_MAPPER.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true);
        // 接受单个值作为数组
        OBJECT_MAPPER.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
    }

    /**
     * 获取ObjectMapper实例
     *
     * @return ObjectMapper实例
     */
    public static ObjectMapper getObjectMapper() {
        return OBJECT_MAPPER;
    }

    /**
     * 将对象转换为JSON字符串
     *
     * @param obj 要转换的对象
     * @return JSON字符串，转换失败返回null
     */
    public static String toJsonString(Object obj) {
        if (obj == null) {
            return null;
        }
        try {
            return OBJECT_MAPPER.writeValueAsString(obj);
        } catch (JsonProcessingException e) {
            log.error("对象转换为JSON字符串失败: {}", e.getMessage(), e);
            return null;
        }
    }

    /**
     * 将对象转换为格式化的JSON字符串
     *
     * @param obj 要转换的对象
     * @return 格式化的JSON字符串，转换失败返回null
     */
    public static String toJsonStringPretty(Object obj) {
        if (obj == null) {
            return null;
        }
        try {
            return OBJECT_MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
        } catch (JsonProcessingException e) {
            log.error("对象转换为格式化JSON字符串失败: {}", e.getMessage(), e);
            return null;
        }
    }

    /**
     * 将JSON字符串转换为指定类型的对象
     *
     * @param jsonString JSON字符串
     * @param clazz      目标类型
     * @param <T>        泛型类型
     * @return 转换后的对象，转换失败返回null
     */
    public static <T> T parseObject(String jsonString, Class<T> clazz) {
        if (jsonString == null || jsonString.trim().isEmpty()) {
            return null;
        }
        try {
            return OBJECT_MAPPER.readValue(jsonString, clazz);
        } catch (JsonProcessingException e) {
            log.error("JSON字符串转换为对象失败: {}", e.getMessage(), e);
            return null;
        }
    }

    /**
     * 将JSON字符串转换为指定类型的对象（使用TypeReference）
     *
     * @param jsonString    JSON字符串
     * @param typeReference 类型引用
     * @param <T>           泛型类型
     * @return 转换后的对象，转换失败返回null
     */
    public static <T> T parseObject(String jsonString, TypeReference<T> typeReference) {
        if (jsonString == null || jsonString.trim().isEmpty()) {
            return null;
        }
        try {
            return OBJECT_MAPPER.readValue(jsonString, typeReference);
        } catch (JsonProcessingException e) {
            log.error("JSON字符串转换为对象失败: {}", e.getMessage(), e);
            return null;
        }
    }

    /**
     * 将JSON字符串转换为List
     *
     * @param jsonString JSON字符串
     * @param clazz      List元素类型
     * @param <T>        泛型类型
     * @return List对象，转换失败返回null
     */
    public static <T> List<T> parseList(String jsonString, Class<T> clazz) {
        if (jsonString == null || jsonString.trim().isEmpty()) {
            return null;
        }
        try {
            return OBJECT_MAPPER.readValue(jsonString, 
                OBJECT_MAPPER.getTypeFactory().constructCollectionType(List.class, clazz));
        } catch (JsonProcessingException e) {
            log.error("JSON字符串转换为List失败: {}", e.getMessage(), e);
            return null;
        }
    }

    /**
     * 将JSON字符串转换为Map
     *
     * @param jsonString JSON字符串
     * @return Map对象，转换失败返回null
     */
    public static Map<String, Object> parseMap(String jsonString) {
        if (jsonString == null || jsonString.trim().isEmpty()) {
            return null;
        }
        try {
            return OBJECT_MAPPER.readValue(jsonString, new TypeReference<Map<String, Object>>() {});
        } catch (JsonProcessingException e) {
            log.error("JSON字符串转换为Map失败: {}", e.getMessage(), e);
            return null;
        }
    }

    /**
     * 将JSON字符串转换为指定类型的Map
     *
     * @param jsonString JSON字符串
     * @param keyClass   键类型
     * @param valueClass 值类型
     * @param <K>        键泛型类型
     * @param <V>        值泛型类型
     * @return Map对象，转换失败返回null
     */
    public static <K, V> Map<K, V> parseMap(String jsonString, Class<K> keyClass, Class<V> valueClass) {
        if (jsonString == null || jsonString.trim().isEmpty()) {
            return null;
        }
        try {
            return OBJECT_MAPPER.readValue(jsonString,
                OBJECT_MAPPER.getTypeFactory().constructMapType(Map.class, keyClass, valueClass));
        } catch (JsonProcessingException e) {
            log.error("JSON字符串转换为Map失败: {}", e.getMessage(), e);
            return null;
        }
    }

    /**
     * 将JSON字符串转换为JsonNode
     *
     * @param jsonString JSON字符串
     * @return JsonNode对象，转换失败返回null
     */
    public static JsonNode parseJsonNode(String jsonString) {
        if (jsonString == null || jsonString.trim().isEmpty()) {
            return null;
        }
        try {
            return OBJECT_MAPPER.readTree(jsonString);
        } catch (JsonProcessingException e) {
            log.error("JSON字符串转换为JsonNode失败: {}", e.getMessage(), e);
            return null;
        }
    }

    /**
     * 从InputStream读取JSON并转换为指定类型的对象
     *
     * @param inputStream 输入流
     * @param clazz       目标类型
     * @param <T>         泛型类型
     * @return 转换后的对象，转换失败返回null
     */
    public static <T> T parseObject(InputStream inputStream, Class<T> clazz) {
        if (inputStream == null) {
            return null;
        }
        try {
            return OBJECT_MAPPER.readValue(inputStream, clazz);
        } catch (IOException e) {
            log.error("从InputStream转换为对象失败: {}", e.getMessage(), e);
            return null;
        }
    }

    /**
     * 从InputStream读取JSON并转换为指定类型的对象（使用TypeReference）
     *
     * @param inputStream   输入流
     * @param typeReference 类型引用
     * @param <T>           泛型类型
     * @return 转换后的对象，转换失败返回null
     */
    public static <T> T parseObject(InputStream inputStream, TypeReference<T> typeReference) {
        if (inputStream == null) {
            return null;
        }
        try {
            return OBJECT_MAPPER.readValue(inputStream, typeReference);
        } catch (IOException e) {
            log.error("从InputStream转换为对象失败: {}", e.getMessage(), e);
            return null;
        }
    }

    /**
     * 对象深度复制（通过JSON序列化/反序列化实现）
     *
     * @param obj   源对象
     * @param clazz 目标类型
     * @param <T>   泛型类型
     * @return 复制后的对象，复制失败返回null
     */
    public static <T> T deepCopy(Object obj, Class<T> clazz) {
        if (obj == null) {
            return null;
        }
        try {
            String json = OBJECT_MAPPER.writeValueAsString(obj);
            return OBJECT_MAPPER.readValue(json, clazz);
        } catch (JsonProcessingException e) {
            log.error("对象深度复制失败: {}", e.getMessage(), e);
            return null;
        }
    }

    /**
     * 判断字符串是否为有效的JSON格式
     *
     * @param jsonString JSON字符串
     * @return true表示有效，false表示无效
     */
    public static boolean isValidJson(String jsonString) {
        if (jsonString == null || jsonString.trim().isEmpty()) {
            return false;
        }
        try {
            OBJECT_MAPPER.readTree(jsonString);
            return true;
        } catch (JsonProcessingException e) {
            return false;
        }
    }

    /**
     * 将对象转换为字节数组
     *
     * @param obj 要转换的对象
     * @return 字节数组，转换失败返回null
     */
    public static byte[] toJsonBytes(Object obj) {
        if (obj == null) {
            return null;
        }
        try {
            return OBJECT_MAPPER.writeValueAsBytes(obj);
        } catch (JsonProcessingException e) {
            log.error("对象转换为字节数组失败: {}", e.getMessage(), e);
            return null;
        }
    }

    /**
     * 从字节数组转换为指定类型的对象
     *
     * @param bytes 字节数组
     * @param clazz 目标类型
     * @param <T>   泛型类型
     * @return 转换后的对象，转换失败返回null
     */
    public static <T> T parseObject(byte[] bytes, Class<T> clazz) {
        if (bytes == null || bytes.length == 0) {
            return null;
        }
        try {
            return OBJECT_MAPPER.readValue(bytes, clazz);
        } catch (IOException e) {
            log.error("字节数组转换为对象失败: {}", e.getMessage(), e);
            return null;
        }
    }

    /**
     * 从字节数组转换为指定类型的对象（使用TypeReference）
     *
     * @param bytes         字节数组
     * @param typeReference 类型引用
     * @param <T>           泛型类型
     * @return 转换后的对象，转换失败返回null
     */
    public static <T> T parseObject(byte[] bytes, TypeReference<T> typeReference) {
        if (bytes == null || bytes.length == 0) {
            return null;
        }
        try {
            return OBJECT_MAPPER.readValue(bytes, typeReference);
        } catch (IOException e) {
            log.error("字节数组转换为对象失败: {}", e.getMessage(), e);
            return null;
        }
    }

    /**
     * 合并两个JSON对象
     *
     * @param mainJson   主JSON对象
     * @param updateJson 要合并的JSON对象
     * @return 合并后的JsonNode，合并失败返回null
     */
    public static JsonNode mergeJson(String mainJson, String updateJson) {
        try {
            JsonNode mainNode = OBJECT_MAPPER.readTree(mainJson);
            JsonNode updateNode = OBJECT_MAPPER.readTree(updateJson);
            return mergeJson(mainNode, updateNode);
        } catch (JsonProcessingException e) {
            log.error("JSON合并失败: {}", e.getMessage(), e);
            return null;
        }
    }

    /**
     * 合并两个JsonNode
     *
     * @param mainNode   主JsonNode
     * @param updateNode 要合并的JsonNode
     * @return 合并后的JsonNode
     */
    public static JsonNode mergeJson(JsonNode mainNode, JsonNode updateNode) {
        if (mainNode == null || updateNode == null) {
            return mainNode != null ? mainNode : updateNode;
        }
        
        if (mainNode.isObject() && updateNode.isObject()) {
            com.fasterxml.jackson.databind.node.ObjectNode result = 
                (com.fasterxml.jackson.databind.node.ObjectNode) mainNode.deepCopy();
            com.fasterxml.jackson.databind.node.ObjectNode update = 
                (com.fasterxml.jackson.databind.node.ObjectNode) updateNode;
            return result.setAll(update);
        }
        
        return updateNode;
    }
}
